若是想要了解 SDN OpenFlow 以及 P4 請不要吝嗇點擊喜歡或是訂閱我喔!(訂閱又不收費XD)
未來有機會也可以跟大家分享我當網管的辛酸血淚史,可以讓人解決問題時可以參考我的文章。
話不多說,我們就累狗!!
再我們程式撰寫方面我們可以將SWITCH,切割成下列幾個小種類
parser MyParser(packet_in packet,
out headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {
state start {
transition parse_ethernet;
}
state parse_ethernet {
packet.extract(hdr.ethernet);
transition select(hdr.ethernet.etherType) {
TYPE_MYTUNNEL: parse_myTunnel;
TYPE_IPV4: parse_ipv4;
default: accept;
}
}
state parse_myTunnel {
packet.extract(hdr.myTunnel);
transition select(hdr.myTunnel.proto_id) {
TYPE_IPV4: parse_ipv4;
default: accept;
}
}
state parse_ipv4 {
packet.extract(hdr.ipv4);
transition accept;
}
}
control MyVerifyChecksum(inout headers hdr, inout metadata meta) {
apply { }
}
control MyComputeChecksum(inout headers hdr, inout metadata meta) {
apply {
update_checksum(
hdr.ipv4.isValid(),
{ hdr.ipv4.version,
hdr.ipv4.ihl,
hdr.ipv4.diffserv,
hdr.ipv4.totalLen,
hdr.ipv4.identification,
hdr.ipv4.flags,
hdr.ipv4.fragOffset,
hdr.ipv4.ttl,
hdr.ipv4.protocol,
hdr.ipv4.srcAddr,
hdr.ipv4.dstAddr },
hdr.ipv4.hdrChecksum,
HashAlgorithm.csum16);
}
}
control MyIngress(inout headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {
counter(MAX_TUNNEL_ID, CounterType.packets_and_bytes) ingressTunnelCounter;
counter(MAX_TUNNEL_ID, CounterType.packets_and_bytes) egressTunnelCounter;
action drop() {
mark_to_drop(standard_metadata);
}
action ipv4_forward(macAddr_t dstAddr, egressSpec_t port) {
standard_metadata.egress_spec = port;
hdr.ethernet.srcAddr = hdr.ethernet.dstAddr;
hdr.ethernet.dstAddr = dstAddr;
hdr.ipv4.ttl = hdr.ipv4.ttl - 1;
}
action myTunnel_ingress(bit<16> dst_id) {
hdr.myTunnel.setValid();
hdr.myTunnel.dst_id = dst_id;
hdr.myTunnel.proto_id = hdr.ethernet.etherType;
hdr.ethernet.etherType = TYPE_MYTUNNEL;
ingressTunnelCounter.count((bit<32>) hdr.myTunnel.dst_id);
}
action myTunnel_forward(egressSpec_t port) {
standard_metadata.egress_spec = port;
}
action myTunnel_egress(macAddr_t dstAddr, egressSpec_t port) {
standard_metadata.egress_spec = port;
hdr.ethernet.dstAddr = dstAddr;
hdr.ethernet.etherType = hdr.myTunnel.proto_id;
hdr.myTunnel.setInvalid();
egressTunnelCounter.count((bit<32>) hdr.myTunnel.dst_id);
}
table ipv4_lpm {
key = {
hdr.ipv4.dstAddr: lpm;
}
actions = {
ipv4_forward;
myTunnel_ingress;
drop;
NoAction;
}
size = 1024;
default_action = NoAction();
}
table myTunnel_exact {
key = {
hdr.myTunnel.dst_id: exact;
}
actions = {
myTunnel_forward;
myTunnel_egress;
drop;
}
size = 1024;
default_action = drop();
}
apply {
if (hdr.ipv4.isValid() && !hdr.myTunnel.isValid()) {
// Process only non-tunneled IPv4 packets.
ipv4_lpm.apply();
}
if (hdr.myTunnel.isValid()) {
// Process all tunneled packets.
myTunnel_exact.apply();
}
}
}
control MyEgress(inout headers hdr,
inout metadata meta,
inout standard_metadata_t standard_metadata) {
apply { }
}
control MyDeparser(packet_out packet, in headers hdr) {
apply {
packet.emit(hdr.ethernet);
packet.emit(hdr.myTunnel);
packet.emit(hdr.ipv4);
}
}
那 P4RUNTIME是甚麼呢?
這邊就與 OpenFlow 協定類似 透過 install flow table來決定 routing 方式
我們透過 controller install flow entries 來達到轉發的目的
def readTableRules(p4info_helper, sw):
"""
Reads the table entries from all tables on the switch.
:param p4info_helper: the P4Info helper
:param sw: the switch connection
"""
print '\n----- Reading tables rules for %s -----' % sw.name
for response in sw.ReadTableEntries():
for entity in response.entities:
entry = entity.table_entry
#
#
print entry
print '-----'
那我們就必須了解 readTable Rules 怎麼做 一樣當成習題!
我們明天再一起講解!
在此付上我的 Reference,我將會以簡短白話的方式來講解 P4 這套語言,若是你/妳不嫌棄可以訂閱我的發文
每天就根據我自己了解的程度來做發文的動作,如果自己對於 P4也有興趣可以先來預習,那我們明天見!
Reference :
P4_turtorial
[(http://docs.google.com/presentation/d/1zliBqsS8IOD4nQUboRRmF_19poeLLDLadD5zLzrTkVc/edit#slide=id.g37fca2850e_6_1802)]